package net.zjitc.yaobei_backed.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.validation.Valid;
import net.zjitc.yaobei_backed.dto.*;
import net.zjitc.yaobei_backed.entity.User;
import net.zjitc.yaobei_backed.repository.UserRepository;
import net.zjitc.yaobei_backed.service.SmsService;
import net.zjitc.yaobei_backed.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/auth")
@CrossOrigin
public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private SmsService smsService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping("/login")
    public ResponseEntity<ApiResponse<LoginResponse>> login(@Valid @RequestBody LoginRequest loginRequest) {
        try {
            System.out.println("LoginController: Attempting login for username: " + loginRequest.getUsername());
            
            // 使用Spring Security进行认证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            loginRequest.getUsername(),
                            loginRequest.getPassword()));

            // 将认证信息存储到安全上下文中
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 生成JWT token
            String token = jwtUtil.generateToken(loginRequest.getUsername());
            long expireTime = System.currentTimeMillis() + 86400000L; // 24小时
            
            // 返回token和过期时间
            LoginResponse loginResponse = new LoginResponse(token, expireTime);
            System.out.println("LoginController: Login successful for username: " + loginRequest.getUsername());
            return ResponseEntity.ok(ApiResponse.success("登录成功", loginResponse));
        } catch (org.springframework.security.authentication.BadCredentialsException e) {
            System.out.println("LoginController: Bad credentials for username: " + loginRequest.getUsername());
            System.out.println("LoginController: Exception message: " + e.getMessage());
            throw e; // 让全局异常处理器处理
        } catch (org.springframework.security.core.userdetails.UsernameNotFoundException e) {
            System.out.println("LoginController: User not found: " + loginRequest.getUsername());
            System.out.println("LoginController: Exception message: " + e.getMessage());
            throw e; // 让全局异常处理器处理
        } catch (Exception e) {
            System.out.println("LoginController: Unexpected error during login: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
    }

    @PostMapping("/send-code")
    public ResponseEntity<ApiResponse<String>> sendCode(@Valid @RequestBody SendCodeRequest request) {
        try {
            // 发送验证码
            String code = smsService.sendVerificationCode(request.getPhone());
            
            // 开发/测试环境返回验证码，生产环境应返回null
            // 生产环境建议注释掉下面这行，只返回成功消息
            return ResponseEntity.ok(ApiResponse.success("验证码已发送", code));
        } catch (Exception e) {
            return ResponseEntity.ok(ApiResponse.error("发送失败：" + e.getMessage()));
        }
    }

    @PostMapping("/phone-login")
    public ResponseEntity<ApiResponse<LoginResponse>> phoneLogin(@Valid @RequestBody PhoneLoginRequest request) {
        // 验证验证码
        if (!smsService.verifyCode(request.getPhone(), request.getCode())) {
            return ResponseEntity.ok(ApiResponse.error(401, "验证码错误或已过期"));
        }

        // 查询或创建用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", request.getPhone());
        User user = userRepository.selectOne(queryWrapper);

        if (user == null) {
            // 新用户，自动注册
            user = new User();
            user.setPhone(request.getPhone());
            user.setUsername(request.getPhone()); // 使用手机号作为用户名
            user.setNickname("用户" + request.getPhone().substring(7)); // 显示后4位
            userRepository.insert(user);
        }

        // 生成JWT token
        String token = jwtUtil.generateToken(user.getUsername());
        long expireTime = System.currentTimeMillis() + 86400000L; // 24小时

        LoginResponse loginResponse = new LoginResponse(token, expireTime);
        return ResponseEntity.ok(ApiResponse.success("登录成功", loginResponse));
    }

    /**
     * 工具端点：生成密码哈希
     * 用于生成正确的 BCrypt 密码哈希，方便更新数据库
     */
    @PostMapping("/tool/generate-password")
    public ResponseEntity<ApiResponse<Map<String, Object>>> generatePassword(@RequestBody Map<String, String> request) {
        String rawPassword = request.get("password");
        if (rawPassword == null || rawPassword.trim().isEmpty()) {
            return ResponseEntity.ok(ApiResponse.error(400, "密码不能为空"));
        }

        String encodedPassword = passwordEncoder.encode(rawPassword);
        Map<String, Object> result = new HashMap<>();
        result.put("rawPassword", rawPassword);
        result.put("encodedPassword", encodedPassword);
        result.put("sql", "UPDATE user SET password = '" + encodedPassword + "' WHERE username = 'your_username';");

        // 验证生成的哈希
        boolean matches = passwordEncoder.matches(rawPassword, encodedPassword);
        result.put("verification", matches ? "成功" : "失败");
        result.put("matches", matches);

        return ResponseEntity.ok(ApiResponse.success("密码哈希生成成功", result));
    }

    /**
     * 工具端点：验证密码哈希
     * 用于验证数据库中的密码哈希是否正确
     */
    @PostMapping("/tool/verify-password")
    public ResponseEntity<ApiResponse<Map<String, Object>>> verifyPassword(@RequestBody Map<String, String> request) {
        String rawPassword = request.get("password");
        String encodedPassword = request.get("encodedPassword");

        if (rawPassword == null || encodedPassword == null) {
            return ResponseEntity.ok(ApiResponse.error(400, "密码和哈希值不能为空"));
        }

        boolean matches = passwordEncoder.matches(rawPassword, encodedPassword);
        Map<String, Object> result = new HashMap<>();
        result.put("rawPassword", rawPassword);
        result.put("encodedPassword", encodedPassword);
        result.put("matches", matches);
        result.put("message", matches ? "密码匹配" : "密码不匹配");

        return ResponseEntity.ok(ApiResponse.success(matches ? "密码匹配" : "密码不匹配", result));
    }
}